import { useState, useEffect, useRef, useContext } from 'react';
import { Checkbox, NavBar, Popup, List, PullToRefresh, Toast } from "antd-mobile";
import { useHistory, useRouteMatch } from "react-router-dom";
import { LockOutline, MoreOutline } from 'antd-mobile-icons';
import { observer } from "mobx-react-lite";
import './style.scss';

import BottomInputBar from '../../../components/BottomInputBar';
import MessageOperations from '../../../components/MessageOperations';
import SelectorOperationsBar from '../../../components/SelectorOperationsBar';
import SingleMessage from '../../../components/SingleMessage';
import HaveReadStatistic from '../../../components/HaveReadStatistic';
import ReplyList from '../../../components/ReplyList';
import EmoReplyBar from '../../../components/EmoReplyBar';
import ChatGroupNotice from '../../../components/ChatGroupNotice';
import AvatarImage from '../../../components/AvatarImage';

import { ChangeMessagesStatus, CustomDataType, MessageDataChangeType, ConversationType, ContentType } from '../../../constants';
import { MySdkStoreContext } from '../../../context';

export default observer(function () {
  const history = useHistory();
  const mySdkStore = useContext(MySdkStoreContext);
  const anchorRef = useRef(null);
  const { params: { cid } } = useRouteMatch();

  const [pagination, setPagination] = useState({ currentCursorId: 0, nextCursorId: 0 });
  // const [messageList, setMessageList] = useState([]);
  const [currentMessageId, setCurrentMessageId] = useState('');
  const [statisticVisible, setStatisticVisible] = useState(false);
  const [isMultiSelecting, setIsMultiSelecting] = useState(false);
  const [selectedMessages, setSelectedMessages] = useState([]);
  const [converInfo, setConverInfo] = useState({});
  const [bottomInputBarProps, setBottomInputBarProps] = useState({visible: true, isVedioEnable: true, isStrech: false, cid, replyProps: null, converInfo: {} });
  const [ChatRecord, setChatRecord] = useState({visible: false, record: [] });
  const [replyListProps, setReplyListProps] = useState({});
  const [messageOperationVisible, setMessageOperationVisible] = useState({visibleMessageId: null});
  const [groupNoticeProps, setGroupNoticeProps] = useState({ visible: false });
  let messageInTouch = false;

  // 获取历史消息
  const getHistoryMessages = async (cursorId = pagination.nextCursorId) => {
    if (!cursorId) {
      return;
    }
    const res = await mySdkStore.sdk.getHistoryMessages({cid, pageSize: 20, cursorId });
    const { current, list, next } = res;
    setPagination({ currentCursorId: cursorId, nextCursorId: next });
    if(list && list.length) {
      // 将拉取到的未读消息置为“已读”状态
      const unReadMsgs = list.filter(msg => !msg.isRead && msg.from?.userId !== mySdkStore.mockConfig.userId);
      if(unReadMsgs.length) {
        mySdkStore.sdk.changeMessagesStatus({cid, type: 'read', msgIds: unReadMsgs});
      }
    }
    mySdkStore.updateCurrentMessageList(cursorId === converInfo.lastMsgId ? list : [...list, ...mySdkStore.currentMessageList])
  }

  // 发送消息失败回调
  const onSendMessageFail = (error) => {
    const { code, message } = error;
    Toast.show(message);
  }

  // 发送消息成功回调 将发送成功的消息展示在聊天窗中
  const onSendMessageOk = (messageData) => {
    if (messageData.cid !== cid) {
      return;
    }
    const newMsgList = [...mySdkStore.currentMessageList];
    newMsgList.push(messageData);
    mySdkStore.updateCurrentMessageList(newMsgList)

    scrollToBottom();
    // 如果是“回复”的消息，处理“被回复”的消息
    if (messageData.quoteMessageId) {
      const addQouteCount = item => {
        if (item.quotedInfo) {
          item.quotedInfo.replyCounter += 1;
        } else {
          item.quotedInfo = {
            beQuoted: true,
            replyCounter: 1,
            topicId: messageData.quoteMessageId
          }
        }
        return item;
      }
      // setMessageList(currentMessageList => currentMessageList.map(item => item.msgId === messageData.quoteMessageId ? addQouteCount(item) : item));

      mySdkStore.updateCurrentMessageList([...mySdkStore.currentMessageList.map(item => item.msgId === messageData.quoteMessageId ? addQouteCount(item) : item)])
      setBottomInputBarProps({ ...bottomInputBarProps, replyProps: null });
    }

    // 列表移除的会话，在发送消息和接收到消息的时候需要再次展示
    if (converInfo.bizParams?.is_hidden === '1') {
      mySdkStore.sdk.addConversationUserMark({ cid, marks: [{ propertyName: 'is_hidden', propertyValue: 0 }] });
    }
  }

  // 挂断音视频回调
  const onRtcHangup = (messageData) => {

    const newMessageList = [...mySdkStore.currentMessageList].map((item) => {
      if (item.roomId === messageData.roomId) {
        item.msgContent.rtcAction = 'hangUp';
        item.msgContent.rtcRoomInfo =
          {
            createTime: item.createTime,
            closeTime: messageData.closeTime,
          }
        item.msgContent.invitedUserRejected = messageData.invitedUserRejected || false;
      }
      return item;
    });
    mySdkStore.updateCurrentMessageList([...newMessageList]);
  }

  // 滚动到底部
  const scrollToBottom = (behavior = 'smooth') => {
    anchorRef.current?.scrollIntoView({ behavior, block: "end", inline: "center" });
  }

  useEffect(() => {
    if(mySdkStore.newMessageData && mySdkStore.newMessageData.length) {
      setTimeout(() => scrollToBottom(), 0);
    }
  }, [mySdkStore.newMessageData]);

  useEffect(() => {
    // 获取当前回话详情
    mySdkStore.setInChatCid(cid);
    mySdkStore.sdk.setCurrentCid(cid).then(async (currentConverInfo) => {
      setConverInfo(currentConverInfo);
      setBottomInputBarProps({ ...bottomInputBarProps, visible: currentConverInfo.type !== ConversationType.Notify, converInfo: currentConverInfo });
      const cursorMsgId = history.location?.state?.msgId || currentConverInfo.lastMsgId;
      await getHistoryMessages(cursorMsgId);
      scrollToBottom('instant');
      // 兼容图片加载完后的高度
      // setTimeout(() => scrollToBottom('instant'), 1500);

      // 判断群公告是否展示
      if (currentConverInfo.notice && +currentConverInfo.bizParams?.isAllowNotice) {
        setGroupNoticeProps({
          visible: true,
          notice: currentConverInfo.notice,
          onClose: () => setGroupNoticeProps({ visible: false })
        });
      }
    });
    mySdkStore.sdk.onSendMessageOk = onSendMessageOk;
    mySdkStore.sdk.onSendMessageFail = onSendMessageFail;
    return () => {
      mySdkStore.updateCurrentMessageList([]);
      mySdkStore.setInChatCid(null);
    }
  }, []);

  const onBack = () => {
    history.goBack();
  }

  // 控制打开群聊天窗已读、未读统计界面
  const handleStatisticVisible = (messageId) => {
    setStatisticVisible(true);
    setCurrentMessageId(messageId);
  }

  // 控制关闭群聊天窗已读、未读统计界面
  const handleStatisticClose = () => {
    setStatisticVisible(false);
    setCurrentMessageId('');
  }

  // 获取选中的多条信息
  const getSelectedMessages = () => {
    return selectedMessages;
  }

  // 点击“批量删除”处理函数
  const handleMulitDeleteOk = (messageIds) => {
    const newMessageList = [...mySdkStore.currentMessageList].map((item) => {
      if (messageIds.indexOf(item.msgId) > -1) {
        item.isDelete = true;
      }
      return item;
    });
    mySdkStore.updateCurrentMessageList([...newMessageList]);
    setIsMultiSelecting(false);
    setSelectedMessages([]);
  }

  // 点击“回复”处理函数 将待回复的messageData参数传递到bottomInputBar组件中
  const handleReply = (msg) => {
    setBottomInputBarProps({
      ...bottomInputBarProps,
      replyProps: msg
    });
  }

  // 点击“重新编辑”处理函数
  const handleReEdit = (text) => {
    setBottomInputBarProps({
      ...bottomInputBarProps,
      reEditProps: { message: text }
    });
  }

  // 点击“x条回复”处理函数 控制打开话题界面
  const handleShowReply = (messageData) => {
    setReplyListProps({
      ...replyListProps,
      visible: true,
      ...messageData
    });
  }

  // 控制关闭话题界面
  const handleReplyListClose = () => {
    setReplyListProps({
      visible: false,
    });
  }

  // 撤回消息回调
  const onRecallOk = (messageData) => {
    const newMessageList = [...mySdkStore.currentMessageList].map((item) => {
      if (item.msgId === messageData.msgId) {
        item.isRecall = true;
      }
      return item;
    });
    mySdkStore.updateCurrentMessageList([...newMessageList]);
  }

  // 删除消息回调
  const onDeleteOK = (messageData) => {
    const newMessageList = [...mySdkStore.currentMessageList].map((item) => {
      if (item.msgId === messageData.msgId) {
        item.isDelete = true;
      }
      return item;
    });
    mySdkStore.updateCurrentMessageList([...newMessageList]);
  }

  // 增加表情回复回调
  const onAddEmojiReply = ({ msgId, instantReplyFaceInfo}) => {
    const addEmoji = messageData => {
     if (messageData.instantReplyFaceInfos) {
      messageData.instantReplyFaceInfos.push(instantReplyFaceInfo)
     } else {
      messageData.instantReplyFaceInfos = [instantReplyFaceInfo]
     }
     return messageData;
    }
    // setMessageList(messageList.map(item => item.msgId === msgId ? addEmoji(item) : item))

    const newMessageList = [...mySdkStore.currentMessageList].map(item => item.msgId === msgId ? addEmoji(item) : item)
    mySdkStore.updateCurrentMessageList([...newMessageList]);
  }

  // 单条消息长按操作框props
  const messageOperationsProps =  {
    cid,
    // 点击“回复”消息回调
    onReply: handleReply,
    // 点击“多选”回调
    onMultiSelect: () => setIsMultiSelecting(true),
    // 点击“稍后处理”回调
    onLater: () => {},
    // 点击“撤回”回调
    onRecall: onRecallOk,
    // 点击”删除“回调
    onDelete: () => {},
    // 点击“emoji icon”图标回调
    onAddEmojiReply: onAddEmojiReply,
    onRtc: () => { },
    // 关闭操作框回调
    onPopoverClose: () => setMessageOperationVisible({ visibleMessageId: null }),
  }

  const singleMessageProps = {
  }

  // 模拟单条消息长按事件
  const handleMessageOperationsTouchStart = (e, msgId, msgType) => {
    e.stopPropagation();
    if(messageInTouch) return;
    messageInTouch = true;

    let messageInTouchTimeoutID: any = setTimeout(() => {
      if(messageInTouch) {
        setMessageOperationVisible({ visibleMessageId: msgId });
        if (msgType === ContentType.Image) {
          // 取消长按时浏览器自动选取文字的默认事件
          window.getSelection()?.removeAllRanges();
        }
      }
      if(messageInTouchTimeoutID) {
        clearTimeout(messageInTouchTimeoutID);
        messageInTouchTimeoutID = null;
      }
    }, 400);
  }

  const handleMessageOperationsTouchEnd = (e) => {
    messageInTouch = false;
  }

  // 点击“聊天记录”类型的消息查看聊天记录
  const handleSingleMessageClick = (e, item) => {
    if(item.removeOperate) return;

    if(item.msgType === 'merged') {
      const { originalMessageIds, originalCid } = item.msgContent;
      mySdkStore.sdk.queryMultiplyMessage({cid: originalCid, msgIds: originalMessageIds}).then(data => {
        setChatRecord({ record: data.list, visible: true });
      });
    }
    e.stopPropagation();
  }

  // 底部输入框点击"+"图标回调，自动滚动到聊天窗底部
  const onBottomInputBarStrechChange = (isStrech) => {
    setBottomInputBarProps({ ...bottomInputBarProps, isStrech });
    if (isStrech) {
      scrollToBottom();
    }
  }
  
  //撤回快捷表情回复
  const onInstantReplyEmojiClick = async (faceContent, messageId) => {
    const { iconId } = faceContent;
    const recallRes = await mySdkStore.sdk.recallFaceReplyFromMsg({ iconId, cid, messageId });
    if(recallRes && recallRes.sendOk) {
      const newMessageList = [...mySdkStore.currentMessageList]
      const itemIndex = newMessageList.findIndex(m => m.msgId === messageId);
      const matchItem = newMessageList[itemIndex];
      const eIndex = matchItem.instantReplyFaceInfos.findIndex(e => e.faceContent.iconId === iconId);
      matchItem.instantReplyFaceInfos.splice(eIndex, 1);
      newMessageList[itemIndex] = matchItem;
      mySdkStore.updateCurrentMessageList([...newMessageList]);
    }
  }

  // 渲染单条消息
  const renderMessage = (item) => {
    const { msgId, from, isDelete, isRecall, msgContent = {}, removeOperate, readStatusVO } = item;
    const isLeft = from?.userId !== mySdkStore.mockConfig?.userId;
    const isCustomSystem = msgContent.dataType === CustomDataType.System;

    // 删除的消息不展示
    if (isDelete) return null;

    if (item.time) {
      return <div key={msgId} className="timeBar">{item.time}</div>
    }

    if (isRecall) {
      // 撤回的消息
      return <div className="center" key={msgId}>
        <SingleMessage {...singleMessageProps} onReEdit={handleReEdit} {...item} type='recall'>{item.message}</SingleMessage>
      </div>
    }

    if (isCustomSystem) {
      // 模拟系统发送的消息
      return <div className="center" key={msgId}>
        <SingleMessage {...singleMessageProps} {...item} type={item.msgType}>{item.message}</SingleMessage>
      </div>
    }

    const MessageContent = <>
      { isMultiSelecting ? <Checkbox value={item.msgId} style={{ margin: isLeft ? '12px 12px 12px 0' : '12px' }} /> : <div></div> }
      {/* 左侧展示发送人头像 */}
      {isLeft &&
        <AvatarImage src={converInfo.singleSession ? converInfo.subAvatarUrl : item.from?.avatarUrl} userName={item.from?.userName} nickName={item.from?.nickName} userId={item.from?.userId} style={{ marginRight: 6, borderRadius: 8, minWidth: 40 }} fit='cover' width={40} height={40} />
      }
      <div className={!isLeft? 'rightContent' : 'leftContent'} id={msgId}>
          { isLeft && <div className="nickName">{ item.from?.userName || item.from?.nickName ||  item.from?.userId }</div> }
          {/* 长按消息处理区域 */}
          <MessageOperations popoverVisible={ messageOperationVisible.visibleMessageId === item.msgId } { ...messageOperationsProps } messageData={item} converInfo={converInfo}>
            <div className="message" onClick={(e) => handleSingleMessageClick(e, item)} onTouchStart={(e) => removeOperate ? null : handleMessageOperationsTouchStart(e, msgId, item.msgType)} onTouchCancel={handleMessageOperationsTouchEnd} onTouchEnd={handleMessageOperationsTouchEnd}>
              {/* 单条消息 按消息类型 进行渲染 */}
              <SingleMessage {...singleMessageProps} {...item} type={item.msgType}></SingleMessage>
              {/* 快捷表情回复区域 */}
              { !!item.instantReplyFaceInfos?.length && <EmoReplyBar onEmojiClick={onInstantReplyEmojiClick} messageId={item.msgId} list={item.instantReplyFaceInfos} /> }
            </div>
          </MessageOperations>
        {/* 底部区域，回复、已读/未读统计等 */}
        <div className="bottomInfo">
          { item.quotedInfo?.beQuoted && <a style={{ marginRight: 8 }} onClick={() => handleShowReply(item)}>{item.quotedInfo.replyCounter}条回复</a> }
          { !!item.privateUsers?.length && <span style={{ marginRight: 8 }}><LockOutline /> 仅你和被指定的人能看到</span>}
          { !isLeft && converInfo.type === ConversationType.Single && (item.isRead ?
            <span className="haveReadMark read">已读</span> :
            <span className="haveReadMark unread">未读</span>
          )}
          { !isLeft && converInfo.type === ConversationType.Group && (readStatusVO?.allRead ?
            <span className="haveReadMark read" onClick={() => handleStatisticVisible(item.msgId)}>全部已读</span> :
            <span className="haveReadMark unread" onClick={() => handleStatisticVisible(item.msgId)}>{readStatusVO?.unReadUserCount || converInfo?.memberCount - 1}人未读</span>
          )}
        </div>
      </div>
    </>

    return <div key={item.msgId} className={`${isLeft ? 'left' : 'right'}Wrap`}>
      <div className={isLeft ? 'left' : 'right'}>
        {MessageContent}
      </div>
    </div>
  }

  // 页面标题
  const getPageTitle = () => {
    switch(converInfo.type) {
      case ConversationType.Single:
        return converInfo.sessionName;
      case ConversationType.Group:
        return converInfo.name;
      case ConversationType.Notify:
        return '工作通知';
    }
  }

  return (<div
      className="chatDetailPage"
      style={{ paddingBottom: bottomInputBarProps.isStrech && !isMultiSelecting ? 190 : isMultiSelecting ? 80 : 47 }}
      onClick={() => setMessageOperationVisible({ visibleMessageId: null })}
    >
        <NavBar style={{ backgroundColor: '#fff', '--border-bottom': '1px #eee solid',}} right={
          <MoreOutline
            style={{ color: 'rgba(0,0,0,.65)', fontSize: 20 }}
            onClick={() => history.push({
              pathname: `/${converInfo.groupSession ? 'chatGroupDetailSetting' : 'chatDetailSetting'}/${cid}`
            })}
          />
          } onBack={() => isMultiSelecting ? setIsMultiSelecting(false) : onBack()}>
        {
          getPageTitle()
        }
      </NavBar>
      <div className="messageBox">
        {/* 下拉刷新 */}
        <PullToRefresh onRefresh={() => getHistoryMessages()}>
          <Checkbox.Group value={selectedMessages} onChange={ val => { setSelectedMessages(val)} }>
            { mySdkStore.currentMessageList.map(renderMessage) }
          </Checkbox.Group>
        </PullToRefresh>
        <div ref={anchorRef} />
      </div>

      {/* 查看消息类型为“聊天记录”的消息，展示完整聊天记录 */}
      <Popup
        visible={ChatRecord.visible}
        onMaskClick={() => {
          setChatRecord({visible: false})
        }}
        onClose={() => {
          setChatRecord({visible: false})
        }}
        destroyOnClose={true}
        showCloseButton={true}
        bodyStyle={{ height: '80vh', borderTopLeftRadius: '8px', borderTopRightRadius: '8px' }}
        bodyClassName="chatDetailPage"
      >
        <List header={ <div style={{ textAlign: 'center', fontSize: '16px', color: 'rgba(0,0,0,0.85)' }}>聊天记录</div>}>
          <div style={{height: 'calc(80vh - 45px)', overflowY: 'scroll', backgroundColor: '#f5f5f9' }}>
            {
              ChatRecord?.record?.map((item) => renderMessage({ ...item, removeOperate: true }))
            }
          </div>
        </List>
      </Popup>
      {/* 底部输入框 或 多选操作条 */}
      { !isMultiSelecting ?
        (bottomInputBarProps.visible ? <BottomInputBar
          {...bottomInputBarProps}
          converInfo={converInfo}
          onStrechChange={onBottomInputBarStrechChange}
          onRtcHangup={onRtcHangup}
        /> : null) :
        <SelectorOperationsBar selectedMessages={selectedMessages} cid={cid} getSelectedMessages={getSelectedMessages} onOk={ () => {setIsMultiSelecting(false); setSelectedMessages([])} } onDeleteOk={handleMulitDeleteOk} />
      }
      {/* 群聊天窗 已读/未读 人数统计 */}
      { statisticVisible && <HaveReadStatistic cid={cid} messageId={currentMessageId} onClose={handleStatisticClose} /> }
      {/* 单条消息回复详情 */}
      { replyListProps.visible && <ReplyList {...replyListProps} onClose={handleReplyListClose} /> }
      {/* 群聊天窗 群公告 */}
      { groupNoticeProps.visible && <ChatGroupNotice {...groupNoticeProps} />}
    </div>
  )
})